package com.siyoumi.sh.modules.jm;

import com.siyoumi.sh.component.ThreadContext;
import com.siyoumi.sh.modules.common.IHandle;
import com.siyoumi.sh.modules.jm.entity.FunAuctionGoods;
import com.siyoumi.sh.modules.jm.entity.FunAuctionMaxInfo;
import com.siyoumi.sh.modules.jm.entity.JmApiData;
import com.siyoumi.sh.modules.jm.entity.JmApiToken;
import com.siyoumi.util.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//积分拍卖
@Slf4j
public class FunAuctionHandle
        extends JmHandleBase
        implements IHandle {
    //fun_auction wan 用户序号 商品ID序号

    @Override
    @SneakyThrows
    public void run() {
        List<String> args = ThreadContext.getArgs();
        if (args.size() < 3) {
            log.error("args参数异常，参考：fun_auction wan 商品ID序号 用户序号，{}", args);
            return;
        }
        String server = args.get(1);
        JmApiData apiData = getApiDataByServer(server);
        if (apiData == null) {
            log.error("args server参数异常，{}", args);
            return;
        }
        setJmApiData(apiData);

        Integer userIndex = XStr.toInt(args.get(2));

        List<JmApiToken> apiTokenArr = getJmApiData().getJmApiTokens();
        if (apiTokenArr.size() <= 0) {
            log.error("未配置TOKEN");
            return;
        }
        if (apiTokenArr.size() - 1 < userIndex) {
            log.error("args 用户序号参数异常，{}", args);
            return;
        }
        JmApiToken apiToken = apiTokenArr.get(userIndex);


        List<FunAuctionGoods> listGoods = funAuctionGoodsList(apiToken);
        List<FunAuctionGoods> listGoodsTrue = new ArrayList<>();

        DateTimeFormatter mmdd = DateTimeFormatter.ofPattern("MM-dd HH:mm");

        Integer index = 0;
        for (FunAuctionGoods goods : listGoods) {
            XReturn rDate = goods.validDate();
            if (rDate.getErrCode() == 20022) {
                //已结束不显示
                continue;
            }
            log.info("[{}]{}: {} - {}", index, goods.getAgoods_name()
                    , XDate.format(goods.getAgoods_date_begin(), mmdd)
                    , XDate.format(goods.getAgoods_date_end(), mmdd));
            index++;

            listGoodsTrue.add(goods);
        }

        Integer goodsIndex;
        if (args.size() >= 4) {
            goodsIndex = XStr.toInt(args.get(3));
        } else {
            String s = "";
            while (true) {
                log.info("请输入需要抢的商品序号：");
                BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                s = br.readLine();
                if (XStr.hasAnyText(s)) {
                    break;
                }
            }
            goodsIndex = XStr.toInt(s, 0);
        }

        if (goodsIndex > (listGoodsTrue.size() - 1)) {
            log.info("你请输入商品序号异常");
            return;
        }

        FunAuctionGoods goods = listGoodsTrue.get(goodsIndex);
        qiang(apiToken, goods);
    }

    /**
     * 开始抢购
     */
    public void qiang(JmApiToken apiToken, FunAuctionGoods goods) {
        log.info("{}-开始竞拍", goods.getAgoods_name());
        log.info("{}-离竞拍结束还剩：{}秒", goods.getAgoods_name(), goods.leftSecond());

        Integer fun = getFun(apiToken);
        log.info("{}-积分总数：{}", apiToken.getName(), fun);

        XReturn r = XReturn.getR(0);
        log.info("等待状态");
        while (true) {
            FunAuctionMaxInfo funMaxInfo = funAuctionGoodsMaxFun(apiToken, goods.getAgoods_id());
            log.info("当前积分最高价：{}", funMaxInfo.getArecord_fun());
            log.info("距离结束还剩：{}秒,服务器结束时间：{}", goods.leftSecond(), XDate.format(goods.getAgoods_date_end(), XDate.DATE_TIME_SHORT_PATTERN));
            if (fun < funMaxInfo.getArecord_fun()) {
                r = XReturn.getR(20090, "积分不足," + funMaxInfo.getArecord_fun() + " > " + fun);
                break;
            }

            if (goods.leftSecond() <= 0) {
                break;
            }

            if (goods.leftSecond() <= 3) {
                log.info("最后3秒进入战斗状态");
                log.info("开始竞拍");
                if (apiToken.getWxFrom().equals(funMaxInfo.getWxuser_id())) {
                    log.info("当前最高价是自己，不再出价");
                    continue;
                }

                int fun1 = XApp.random(2, 9);
                int funAuction = funMaxInfo.getArecord_fun() + fun1 * 100; //竞拍价

                r = funAuction(apiToken, goods.getAgoods_id(), funAuction);
                if (r.getErrCode() == 30254 || r.getErrCode() == 30264 || r.ok()) {
                    continue;
                } else {
                    break;
                }
            } else if (goods.leftSecond() <= 30) {
                log.info("最后30秒进入作战状态");

                sleepAndLog(1);
            } else {
                //更新商品最新信息
                FunAuctionGoods nowGoods = funAuctionGoodsInfo(apiToken, goods.getAgoods_id());
                if (nowGoods != null) {
                    goods = nowGoods;
                }
                sleepAndLog(30);
            }
        }

        if (r.err()) {
            sendMsg(goods.getAgoods_name() + ":" + XJson.toJSONString(r));
            return;
        }
    }


    //出价
    public XReturn funAuction(JmApiToken apiToken, String goodsId, int fun) {
        String apiUrl = XStr.concat(getApiRoot(), "__api_java__/z_app/fun_auction_b/web/zz_api__api_x_info__funcAuction?"
                , "type=&site_id=", getSiteId()
                , "&goods_id=", goodsId
                , "&fun=" + fun
                , "&", apiToken.getWxFromQuery()
        );

        XReturn r = forApi(apiUrl);
        return r;
    }

    //获取当前积分最高价
    public FunAuctionMaxInfo funAuctionGoodsMaxFun(JmApiToken apiToken, String goodsId) {
        String apiUrl = XStr.concat(getApiRoot(), "__api_java__/z_app/fun_auction_b/web/zz_api__api_x_info__funcAuctionList?"
                , "type=&site_id=", getSiteId()
                , "&goods_id=", goodsId
                , "&", apiToken.getWxFromQuery()
        );

        FunAuctionMaxInfo info = new FunAuctionMaxInfo();

        XReturn r = forApi(apiUrl);
        List<Map<String, Object>> list = r.getData("list");
        if (list.size() <= 0) {
            return info;
        }


        Map<String, Object> item = list.get(0);
        info.setWxuser_id((String) item.get("wxuser_id"));
        info.setArecord_fun((Integer) item.get("arecord_fun"));

        return info;
    }

    //竞拍商品列表
    public List<FunAuctionGoods> funAuctionGoodsList(JmApiToken apiToken) {
        String apiUrl = XStr.concat(getApiRoot(), "__api_java__/z_app/fun_auction_b/web/zz_api__api_x__funcListGoods?"
                , "type=1&site_id=", getSiteId()
                , "&", apiToken.getWxFromQuery()
        );

        List<FunAuctionGoods> listGoods = new ArrayList<>();
        XReturn r = forApi(apiUrl);
        if (r.err()) {
            return listGoods;
        }

        List<Map<String, Object>> list = r.getData("list");
        for (Map<String, Object> data : list) {
            FunAuctionGoods goods = new FunAuctionGoods();
            goods.setAgoods_date_begin(XDate.parse((String) data.get("agoods_date_begin")));
            goods.setAgoods_date_end(XDate.parse((String) data.get("agoods_date_end")));
            goods.setAgoods_name((String) data.get("agoods_name"));
            goods.setAgoods_id((String) data.get("agoods_id"));
            goods.setFun_max((Integer) data.get("fun_max"));

            listGoods.add(goods);
        }

        return listGoods;
    }

    //竞拍商品详情
    public FunAuctionGoods funAuctionGoodsInfo(JmApiToken apiToken, String goodsId) {
        String apiUrl = XStr.concat(getApiRoot(), "__api_java__/z_app/fun_auction_b/web/zz_api__api_x_info__funcGoodsInfo?"
                , "type=&site_id=", getSiteId()
                , "&goods_id=", goodsId
                , "&", apiToken.getWxFromQuery()
        );

        XReturn r = forApi(apiUrl);
        if (r.err()) {
            return null;
        }

        Map<String, Object> data = r.getData("goods");
        FunAuctionGoods goods = new FunAuctionGoods();
        goods.setAgoods_date_begin(XDate.parse((String) data.get("agoods_date_begin")));
        goods.setAgoods_date_end(XDate.parse((String) data.get("agoods_date_end")));
        goods.setAgoods_name((String) data.get("psend_name"));
        goods.setAgoods_id((String) data.get("agoods_id"));

        goods.updateDateEnd((Integer) data.get("left_s"));

        return goods;
    }
}
